package cc.unitmesh.devins.idea.renderer.terminal

import androidx.compose.foundation.background
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import cc.unitmesh.devins.idea.compose.IdeaLaunchedEffect
import cc.unitmesh.devins.idea.theme.IdeaAutoDevColors
import org.jetbrains.jewel.foundation.theme.JewelTheme
import org.jetbrains.jewel.ui.component.Text

/**
 * Jewel-themed ANSI terminal renderer for IntelliJ IDEA.
 * 
 * Renders terminal output with ANSI escape sequence support including:
 * - Colors (16 standard colors + 256 color palette)
 * - Text styles (bold, italic, underline, dim)
 * - Cursor movements and screen manipulation
 * 
 * Uses Jewel theme colors for better integration with IntelliJ IDEA UI.
 * 
 * @param ansiText Text containing ANSI escape sequences
 * @param modifier Modifier for the terminal container
 * @param maxHeight Maximum height of the terminal display in dp
 * @param backgroundColor Background color (defaults to Jewel panel background)
 */
@Composable
fun IdeaAnsiTerminalRenderer(
    ansiText: String,
    modifier: Modifier = Modifier,
    maxHeight: Int = 600,
    backgroundColor: Color = Color(0xFF9E9E9E)
) {
    var terminalState by remember { mutableStateOf(TerminalState()) }

    // Parse the ANSI text when it changes
    IdeaLaunchedEffect(ansiText) {
        terminalState = AnsiParser.parse(ansiText, terminalState.clearScreen())
    }

    IdeaTerminalRenderer(
        terminalState = terminalState,
        modifier = modifier,
        showCursor = false,
        maxHeight = maxHeight,
        backgroundColor = backgroundColor
    )
}

/**
 * Core terminal renderer component using Jewel theming.
 */
@Composable
private fun IdeaTerminalRenderer(
    terminalState: TerminalState,
    modifier: Modifier = Modifier,
    showCursor: Boolean = false,
    maxHeight: Int = 600,
    backgroundColor: Color = Color(0xFF9E9E9E)
) {
    val defaultForeground = Color(0xFF9E9E9E)
    val verticalScrollState = rememberScrollState()
    val horizontalScrollState = rememberScrollState()

    Box(
        modifier = modifier
            .background(backgroundColor)
            .heightIn(max = maxHeight.dp)
            .fillMaxWidth()
    ) {
        Column(
            modifier = Modifier
                .verticalScroll(verticalScrollState)
                .horizontalScroll(horizontalScrollState)
                .padding(12.dp)
        ) {
            val visibleLines = terminalState.getVisibleLines()

            visibleLines.forEachIndexed { lineIndex, line ->
                IdeaTerminalLineRenderer(
                    line = line,
                    defaultForeground = defaultForeground,
                    showCursor = showCursor && lineIndex == terminalState.cursorY,
                    cursorX = if (lineIndex == terminalState.cursorY) terminalState.cursorX else -1
                )
            }

            // Show cursor on empty line if at the end
            if (showCursor && terminalState.cursorY >= visibleLines.size) {
                IdeaCursorIndicator()
            }
        }
    }
}

/**
 * Renders a single terminal line with styled text using Jewel components.
 */
@Composable
private fun IdeaTerminalLineRenderer(
    line: TerminalLine,
    defaultForeground: Color,
    showCursor: Boolean,
    cursorX: Int
) {
    val annotatedString = buildAnnotatedString {
        line.cells.forEachIndexed { index, cell ->
            val fgColor = getCellColor(cell, defaultForeground, isBackground = false)
            val bgColor = getCellBackgroundColor(cell)
            val alpha = if (cell.dim) 0.6f else 1.0f

            pushStyle(
                SpanStyle(
                    color = fgColor.copy(alpha = alpha),
                    background = bgColor,
                    fontWeight = if (cell.bold) FontWeight.Bold else FontWeight.Normal,
                    fontStyle = if (cell.italic) FontStyle.Italic else FontStyle.Normal,
                    textDecoration = if (cell.underline) TextDecoration.Underline else null
                )
            )

            append(cell.char)
            pop()
        }

        // Add cursor if needed
        if (showCursor && cursorX >= 0) {
            // Ensure we have enough space for cursor
            while (length <= cursorX) {
                append(' ')
            }
        }
    }

    Row {
        Text(
            text = annotatedString,
            style = JewelTheme.defaultTextStyle.copy(
                fontFamily = FontFamily.Monospace,
                fontSize = 12.sp,
                lineHeight = 18.sp
            ),
            modifier = Modifier.padding(vertical = 1.dp)
        )

        if (showCursor && cursorX >= 0 && cursorX >= line.cells.size) {
            IdeaCursorIndicator()
        }
    }
}

/**
 * Get the foreground color for a cell, handling inverse video.
 */
private fun getCellColor(cell: TerminalCell, defaultColor: Color, isBackground: Boolean): Color {
    val fg = cell.foregroundColor ?: defaultColor
    val bg = cell.backgroundColor ?: Color.Transparent

    return if (cell.inverse) {
        if (isBackground) fg else bg.takeIf { it != Color.Transparent } ?: defaultColor
    } else {
        if (isBackground) bg else fg
    }
}

/**
 * Get the background color for a cell.
 */
private fun getCellBackgroundColor(cell: TerminalCell): Color {
    val bg = cell.backgroundColor ?: Color.Transparent
    val fg = cell.foregroundColor ?: Color.Transparent

    return if (cell.inverse) {
        fg.takeIf { it != Color.Transparent } ?: Color.Transparent
    } else {
        bg
    }
}

/**
 * Cursor indicator for live terminals.
 */
@Composable
private fun IdeaCursorIndicator() {
    Box(
        modifier = Modifier
            .size(width = 8.dp, height = 16.dp)
            .background(Color(0xFF26C6DA).copy(alpha = 0.7f))
    )
}

